home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / sbin / rc < prev    next >
Text File  |  2006-05-25  |  20KB  |  797 lines

  1. #!/bin/bash
  2. # Copyright 1999-2005 Gentoo Foundation
  3. # Distributed under the terms of the GNU General Public License v2
  4. # $Header$
  5.  
  6. trap ":" INT QUIT TSTP
  7. source /sbin/functions.sh
  8. # Only source this when this is a livecd booting ...
  9. [ -f /sbin/livecd-functions.sh ] && source /sbin/livecd-functions.sh
  10. umask 022
  11.  
  12. try() {
  13.     local errstr
  14.     local retval=0
  15.     
  16.     if [ -c /dev/null ]; then
  17.         errstr="$((eval $*) 2>&1 >/dev/null)"
  18.     else
  19.         errstr="$((eval $*) 2>&1)"
  20.     fi
  21.     retval=$?
  22.     if [ "${retval}" -ne 0 ]
  23.     then
  24.         splash "critical" &
  25.  
  26.         echo -e "${ENDCOL}${NORMAL}[${BAD} oops ${NORMAL}]"
  27.         echo
  28.         eerror "The \"${1}\" command failed with error:"
  29.         echo
  30.         echo "${errstr#*: }"
  31.         echo
  32.         eerror "Since this is a critical task, startup cannot continue."
  33.         echo
  34.         /sbin/sulogin ${CONSOLE}
  35.         einfo "Unmounting filesystems"
  36.         if [ -c /dev/null ]; then
  37.             /bin/mount -a -o remount,ro &>/dev/null
  38.         else
  39.             /bin/mount -a -o remount,ro
  40.         fi
  41.         einfo "Rebooting"
  42.         /sbin/reboot -f
  43.     fi
  44.     
  45.     return ${retval}
  46. }
  47.  
  48. # Check that $1 exists ...
  49. check_statedir() {
  50.     [ -z "$1" ] && return 0
  51.  
  52.     if [ ! -d "$1" ] ; then
  53.         if ! mkdir -p "$1" &>/dev/null ; then
  54.             splash "critical" &
  55.             echo
  56.             eerror "For Gentoo to function properly, \"$1\" needs to exist."
  57.             if [[ ${RC_FORCE_AUTO} == "yes" ]] ; then
  58.                 eerror "Attempting to create \"$1\" for you ..."
  59.                 mount -o remount,rw /
  60.                 mkdir -p "$1"
  61.             else
  62.                 eerror "Please mount your root partition read/write, and execute:"
  63.                 echo
  64.                 eerror "  # mkdir -p $1"
  65.                 echo; echo
  66.                 /sbin/sulogin ${CONSOLE}
  67.             fi
  68.             einfo "Unmounting filesystems"
  69.             /bin/mount -a -o remount,ro &>/dev/null
  70.             einfo "Rebooting"
  71.             /sbin/reboot -f
  72.         fi
  73.     fi
  74.  
  75.     return 0
  76. }
  77.  
  78. get_critical_services() {
  79.     local x=
  80.     CRITICAL_SERVICES=
  81.     
  82.     if [ -f "/etc/runlevels/${BOOTLEVEL}/.critical" ]
  83.     then
  84.         for x in $(< /etc/runlevels/${BOOTLEVEL}/.critical)
  85.         do
  86.             CRITICAL_SERVICES="${CRITICAL_SERVICES} ${x##*/}"
  87.         done
  88.     else
  89.         CRITICAL_SERVICES="checkroot hostname modules checkfs localmount clock bootmisc"
  90.     fi
  91.  
  92.     export CRITICAL_SERVICES
  93.  
  94.     return 0
  95. }
  96.  
  97. # Save $1
  98. argv1="$1"
  99.  
  100. # First time boot stuff goes here.  Note that 'sysinit' is an internal runlevel
  101. # used to bring up local filesystems, and should not be started with /sbin/rc
  102. # directly ...
  103. if [ "${RUNLEVEL}" = "S" -a "${argv1}" = "sysinit" ]
  104. then
  105.     # Setup initial $PATH just in case
  106.     PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}"
  107.  
  108.     # Help users recover their systems incase these go missing
  109.     [ -c /dev/null ] && dev_null=1 || dev_null=0
  110.     [ -c /dev/console ] && dev_console=1 || dev_console=0
  111.  
  112.         echo
  113.         echo -e "${GOOD}Mini-Pentoo 2006.1; ${BRACKET}http://www.pentoo.ch/${NORMAL}"
  114.         echo -e " Copyright 2006 Michael Zanetta grimmlin@pentoo.ch"
  115.         echo -e "            and Jeremy Dimsdale sleepless@pentoo.ch"
  116.         echo -e " Distributed under GPL"
  117.         echo
  118.  
  119.     check_statedir /proc
  120.  
  121.     ebegin "Mounting proc at /proc"
  122.     if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
  123.         mntcmd=$(get_mount_fstab /proc)
  124.     else
  125.         unset mntcmd
  126.     fi
  127.     try mount -n ${mntcmd:--t proc proc /proc}
  128.     eend $?
  129.  
  130.     # Read off the kernel commandline to see if there's any special settings
  131.     # especially check to see if we need to set the  CDBOOT environment variable
  132.     # Note: /proc MUST be mounted
  133.     [ -f /sbin/livecd-functions.sh ] && livecd_read_commandline
  134.  
  135.     if [ "$(get_KV)" -ge "$(KV_to_int '2.6.0')" ] ; then
  136.         if [[ -d /sys ]] ; then
  137.             ebegin "Mounting sysfs at /sys"
  138.             if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
  139.                 mntcmd=$(get_mount_fstab /sys)
  140.             else
  141.                 unset mntcmd
  142.             fi
  143.             try mount -n ${mntcmd:--t sysfs sysfs /sys}
  144.             eend $?
  145.         else
  146.             ewarn "No /sys to mount sysfs needed in 2.6 and later kernels!"
  147.         fi
  148.     fi
  149.  
  150.     check_statedir /dev
  151.  
  152.     # Fix weird bug where there is a /dev/.devfsd in a unmounted /dev
  153.     devfs_automounted="no"
  154.     if [ -e "/dev/.devfsd" ]
  155.     then
  156.         mymounts="$(awk '($3 == "devfs") { print "yes"; exit 0 }' /proc/mounts)"
  157.         if [ "${mymounts}" != "yes" ]
  158.         then
  159.             rm -f /dev/.devfsd
  160.         else
  161.             devfs_automounted="yes"
  162.         fi
  163.     fi
  164.  
  165.     # Try to figure out how the user wants /dev handled
  166.     #  - check $RC_DEVICES from /etc/conf.d/rc
  167.     #  - check boot parameters
  168.     #  - make sure the required binaries exist
  169.     #  - make sure the kernel has support
  170.     if [ "${RC_DEVICES}" = "static" ]
  171.     then
  172.         ebegin "Using existing device nodes in /dev"
  173.         eend 0
  174.     else
  175.         fellback_to_devfs="no"
  176.         case "${RC_DEVICES}" in
  177.             devfs)    devfs="yes"
  178.                     udev="no"
  179.                     ;;
  180.             udev)    devfs="yes"
  181.                     udev="yes"
  182.                     fellback_to_devfs="yes"
  183.                     ;;
  184.             auto|*)    devfs="yes"
  185.                     udev="yes"
  186.                     ;;
  187.         esac
  188.  
  189.         # Check udev prerequisites and kernel params
  190.         if [ "${udev}" = "yes" ]
  191.         then
  192.             if get_bootparam "noudev" || \
  193.                [ ! -x /sbin/udev -o ${devfs_automounted} = "yes" ] || \
  194.                [ "$(get_KV)" -lt "$(KV_to_int '2.6.0')" ]
  195.             then
  196.                 udev="no"
  197.             fi
  198.         fi
  199.  
  200.         # Check devfs prerequisites and kernel params
  201.         if [ "${devfs}" = "yes" ]
  202.         then
  203.             if get_bootparam "nodevfs" || [ "${udev}" = "yes" ]
  204.             then
  205.                 devfs="no"
  206.             fi
  207.         fi
  208.  
  209.         # Actually start setting up /dev now
  210.         if [[ ${udev} == "yes" ]] ; then
  211.             start_addon udev
  212.  
  213.         # With devfs, /dev can be mounted by the kernel ...
  214.         elif [[ ${devfs} == "yes" ]] ; then
  215.             start_addon devfs
  216.  
  217.             # Did the user want udev in the config file but for 
  218.             # some reason, udev support didnt work out ?
  219.             if [[ ${fellback_to_devfs} == "yes" ]] ; then
  220.                 ewarn "You wanted udev but support for it was not available!"
  221.                 ewarn "Please review your system after it's booted!"
  222.             fi
  223.         fi
  224.  
  225.         # OK, if we got here, things are probably not right :)
  226.         if [[ ${devfs} == "no" && ${udev} == "no" ]] ; then
  227.             clear
  228.             echo
  229.             einfo "The Gentoo Linux system initialization scripts have detected that"
  230.             einfo "your system does not support UDEV.  Since Gentoo Linux has been"
  231.             einfo "designed with dynamic /dev in mind, it is highly suggested that you"
  232.             einfo "emerge sys-fs/udev and configure your system to use it."
  233.             einfo "Please read the Gentoo Handbook for more information!"
  234.             echo
  235.             einfo "    http://www.gentoo.org/doc/en/handbook/"
  236.             echo
  237.             einfo "Thanks for using Gentoo! :)"
  238.             echo
  239.             read -t 15 -p "(hit Enter to continue or wait 15 seconds ...)"
  240.         fi
  241.     fi
  242.  
  243.     # From linux-2.5.68 we need to mount /dev/pts again ...
  244.     if [ "$(get_KV)" -ge "$(KV_to_int '2.5.68')" ]
  245.     then
  246.         have_devpts="$(awk '($2 == "devpts") { print "yes"; exit 0 }' /proc/filesystems)"
  247.  
  248.         if [ "${have_devpts}" = "yes" ]
  249.         then
  250.             # Only try to create /dev/pts if we have /dev mounted dynamically,
  251.             # else it might fail as / might be still mounted readonly.
  252.             if [ ! -d /dev/pts ] && \
  253.                [ "${devfs}" = "yes" -o "${udev}" = "yes" ]
  254.             then
  255.                 # Make sure we have /dev/pts
  256.                 mkdir -p /dev/pts &>/dev/null || \
  257.                     ewarn "Could not create /dev/pts!"
  258.             fi
  259.  
  260.             if [[ -d /dev/pts ]] ; then
  261.                 ebegin "Mounting devpts at /dev/pts"
  262.                 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
  263.                     mntcmd=$(get_mount_fstab /dev/pts)
  264.                 else
  265.                     unset mntcmd
  266.                 fi
  267.                 try mount -n ${mntcmd:--t devpts -o gid=5,mode=0620 devpts /dev/pts}
  268.                 eend $?
  269.             fi
  270.         fi
  271.     fi
  272.  
  273.     # Start logging console output since we have all /dev stuff setup
  274.     bootlog start
  275.  
  276.     # Swap needs to be activated *after* /dev has been fully setup so that
  277.     # the fstab can be properly parsed.  This first pass we send to /dev/null
  278.     # in case the user has swap points setup on different partitions.  We 
  279.     # will run swapon again in localmount and that one will report errors.
  280.     ebegin "Activating (possible) swap"
  281.     /sbin/swapon -a >& /dev/null
  282.     eend 0
  283.  
  284.     # Set the console loglevel to 1 for a cleaner boot
  285.     # the logger should anyhow dump the ring-0 buffer at start to the
  286.     # logs, and that with dmesg can be used to check for problems
  287.     /bin/dmesg -n 1
  288.  
  289.         # Try to load usbstick stuff
  290.         if [ -f "/sbin/livecd-functions.sh" -a -n "${CDBOOT}" ]; then
  291.                 ebegin "Trying to load the Pentoo config from usbstick"
  292.                 /usr/sbin/loadptconf
  293.                 eend 0
  294.         fi
  295.  
  296.     # We set the forced softlevel from the kernel command line
  297.     # It needs to be run right after proc is mounted for the
  298.     # boot runlevel
  299.     setup_defaultlevels
  300.  
  301.     # $BOOT can be used by rc-scripts to test if it is the first time
  302.     # the 'boot' runlevel is executed.  Now also needed by some stuff in
  303.     # the 'sysinit' runlevel ...
  304.     export BOOT="yes"
  305.  
  306.     start_critical_service() {
  307.         (
  308.         local retval=
  309.         local service=$1
  310.         # Needed for some addons like dm-crypt that starts in critical services
  311.         local myservice=$1
  312.  
  313.         source "/etc/init.d/${service}" || eerror "Failed to source /etc/init.d/${service}"
  314.         retval=$?
  315.         [ "${retval}" -ne 0 ] && return "${retval}"
  316.         [ -e "/etc/conf.d/${service}" ] && source "/etc/conf.d/${service}"
  317.         source /etc/rc.conf
  318.  
  319.         start || eerror "Failed to start /etc/init.d/${service}"
  320.         retval=$?
  321.  
  322.         return "${retval}"
  323.         )
  324.     }
  325.  
  326.     # We first try to find a locally defined list of critical services
  327.     # for a particular runlevel.  If we cannot find it, we use the
  328.     # defaults.
  329.     get_critical_services
  330.  
  331.     splash "rc_init" "${argv1}"
  332.  
  333.     # We do not want to break compatibility, so we do not fully integrate
  334.     # these into /sbin/rc, but rather start them by hand ...
  335.     for x in ${CRITICAL_SERVICES}
  336.     do
  337.         splash "svc_start" "${x}"
  338.  
  339.         if ! start_critical_service "${x}"
  340.         then
  341.             splash "critical" &>/dev/null &
  342.             
  343.             echo
  344.             eerror "One of more critical startup scripts failed to start!"
  345.             eerror "Please correct this, and reboot ..."
  346.             echo; echo
  347.             /sbin/sulogin ${CONSOLE}
  348.             einfo "Unmounting filesystems"
  349.             /bin/mount -a -o remount,ro &>/dev/null
  350.             einfo "Rebooting"
  351.             /sbin/reboot -f
  352.         fi
  353.  
  354.         splash "svc_started" "${x}" "0"
  355.     done
  356.  
  357.     # /var/log should be writable now, so starting saving the boot output
  358.     bootlog sync
  359.  
  360.     # have to run this after /var/run is mounted rw #85304
  361.     if [ -x /sbin/irqbalance -a "$(get_KV)" -ge "$(KV_to_int '2.5.0')" ]
  362.     then
  363.         ebegin "Starting irqbalance"
  364.         /sbin/irqbalance
  365.         eend $?
  366.     fi
  367.  
  368.     # Check that $svcdir exists ...
  369.     check_statedir "${svcdir}"
  370.  
  371.     # Should we use tmpfs/ramfs/ramdisk for caching dependency and 
  372.     # general initscript data?  Note that the 'gentoo=<fs>' kernel 
  373.     # option should override any other setting ...
  374.     for fs in tmpfs ramfs ramdisk
  375.     do
  376.         if get_bootparam "${fs}"
  377.         then
  378.             svcmount="yes"
  379.             svcfstype="${fs}"
  380.             break
  381.         fi
  382.     done
  383.     if [ "${svcmount}" = "yes" ]
  384.     then
  385.         ebegin "Mounting ${svcfstype} at ${svcdir}"
  386.         case "${svcfstype}" in
  387.         ramfs)
  388.             try mount -t ramfs svcdir "${svcdir}" \
  389.                 -o rw,mode=0755,size="${svcsize}"k
  390.             ;;
  391.         ramdisk)
  392.             try dd if=/dev/zero of=/dev/ram0 bs=1k count="${svcsize}"
  393.             try /sbin/mke2fs -i 1024 -vm0 /dev/ram0 "${svcsize}"
  394.             try mount -t ext2 /dev/ram0 "${svcdir}" -o rw
  395.             ;;
  396.         tmpfs|*)
  397.             try mount -t tmpfs svcdir "${svcdir}" \
  398.                 -o rw,mode=0755,size="${svcsize}"k
  399.             ;;
  400.         esac
  401.         eend 0
  402.     fi
  403.  
  404.     # If booting off CD, we want to update inittab before setting the runlevel
  405.     if [ -f "/sbin/livecd-functions.sh" -a -n "${CDBOOT}" ]
  406.     then
  407.         ebegin "Updating inittab"
  408.         livecd_fix_inittab
  409.         eend $?
  410.         /sbin/telinit q &>/dev/null
  411.     fi
  412.  
  413.     # Clear $svcdir from stale entries, but leave the caches around, as it
  414.     # should help speed things up a bit
  415.     rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
  416.              grep -ve '\(depcache\|deptree\|envcache\)')
  417.  
  418.     # Update the dependency cache
  419.     /sbin/depscan.sh
  420.  
  421.     # Now that the dependency cache are up to date, make sure these
  422.     # are marked as started ...
  423.     (
  424.         # Needed for mark_service_started()
  425.         source "${svclib}/sh/rc-services.sh"
  426.         
  427.         for x in ${CRITICAL_SERVICES}
  428.         do
  429.             mark_service_started "${x}"
  430.         done
  431.     )
  432.  
  433.     # If the user's /dev/null or /dev/console are missing, we 
  434.     # should help them out and explain how to rectify the situation
  435.     if [ ${dev_null} -eq 0 -o ${dev_console} -eq 0 ] \
  436.         && [ -e /usr/share/baselayout/issue.devfix ]
  437.     then
  438.         # Backup current /etc/issue
  439.         if [ -e /etc/issue -a ! -e /etc/issue.devfix ]
  440.         then
  441.             mv /etc/issue /etc/issue.devfix
  442.         fi
  443.  
  444.         cp /usr/share/baselayout/issue.devfix /etc/issue
  445.     fi
  446.  
  447.     # Setup login records ... this has to be done here because when 
  448.     # we exit this runlevel, init will write a boot record to utmp
  449.     # If /var/run is readonly, then print a warning, not errors
  450.     if touch /var/run/utmp 2>/dev/null
  451.     then
  452.         > /var/run/utmp
  453.         touch /var/log/wtmp
  454.         chgrp utmp /var/run/utmp /var/log/wtmp
  455.         chmod 0664 /var/run/utmp /var/log/wtmp
  456.         # Remove /var/run/utmpx (bug from the past)
  457.         rm -f /var/run/utmpx
  458.     else
  459.         ewarn "Skipping /var/run/utmp initialization (ro root?)"
  460.     fi
  461.  
  462.     # sysinit is now done, so allow init scripts to run normally
  463.     [[ -e /dev/.rcsysinit ]] && rm -f /dev/.rcsysinit
  464.  
  465.     # All done logging
  466.     bootlog quit
  467.  
  468.     exit 0
  469. fi # Sysinit ends here
  470.  
  471. if [ "${RUNLEVEL}" = "S" -a "${argv1}" = "boot" ]
  472. then
  473.     setup_defaultlevels
  474.  
  475.     if [ -n "${DEFAULTLEVEL}" -a "${DEFAULTLEVEL}" != "default" ]
  476.     then
  477.         # Setup our default runlevel runlevel that will be run
  478.         # the first time /sbin/rc is called with argv1 != sysinit|boot
  479.         echo "${DEFAULTLEVEL}" > "${svcdir}/ksoftlevel"
  480.     fi
  481.     
  482.     # $BOOT can be used by rc-scripts to test if it is the first time
  483.     # the 'boot' runlevel is executed
  484.     export BOOT="yes"
  485.  
  486.     # We reset argv1 to the bootlevel given on the kernel command line
  487.     # if there is one
  488.     argv1="${BOOTLEVEL}"
  489.     
  490. elif [ "${RUNLEVEL}" != "S" -a -e "${svcdir}/ksoftlevel" ]
  491. then
  492.     argv1="$(< ${svcdir}/ksoftlevel)"
  493.     rm -f "${svcdir}/ksoftlevel"
  494. fi
  495.  
  496. source "${svclib}/sh/rc-services.sh"
  497. source "${svclib}/sh/rc-daemon.sh"
  498.  
  499. if [ -f "${svcdir}/softlevel" ]
  500. then
  501.     # Set OLDSOFTLEVEL if we had a valid SOFTLEVEL
  502.     export OLDSOFTLEVEL="$(< ${svcdir}/softlevel)"
  503. else
  504.     export OLDSOFTLEVEL=
  505. fi
  506.     
  507. if [ -z "${argv1}" ]
  508. then
  509.     if [ -f "${svcdir}/softlevel" ]
  510.     then
  511.         export SOFTLEVEL="$(< ${svcdir}/softlevel)"
  512.     else
  513.         export SOFTLEVEL="${BOOTLEVEL}"
  514.     fi
  515. else
  516.     export SOFTLEVEL="${argv1}"
  517. fi
  518.  
  519. if [ ! -f "${svcdir}/softlevel" ]
  520. then
  521.     echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
  522. fi
  523.  
  524. # For keeping a list of services that fails during boot/halt
  525. if [ ! -d "${svcdir}/failed" ]
  526. then
  527.     mkdir -p -m 0755 "${svcdir}/failed"
  528. else
  529.     rm -rf "${svcdir}"/failed/*
  530. fi
  531.  
  532. splash "rc_init" "${argv1}"
  533.  
  534. if [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
  535. then
  536.     myscripts=
  537.  
  538. elif [ "${SOFTLEVEL}" = "single" ]
  539. then
  540.     get_critical_services
  541.  
  542.     myscripts="${CRITICAL_SERVICES}"
  543.     
  544. elif [ ! -d "/etc/runlevels/${SOFTLEVEL}" ]
  545. then
  546.     eerror "ERROR:  runlevel ${SOFTLEVEL} does not exist; exiting ..."
  547.     exit 1
  548. else
  549.     myscripts=
  550.     if [ "${SOFTLEVEL}" != "${BOOTLEVEL}" ]
  551.     then
  552.         # Normal runlevels *include* boot scripts
  553.         mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
  554.         mylevels="${mylevels} $(dolisting /etc/runlevels/${BOOTLEVEL}/)"
  555.     else
  556.         # Non-normal runlevels don't include boot scripts as default
  557.         mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
  558.     fi
  559.     
  560.     [ "${OLDSOFTLEVEL}" = "${BOOTLEVEL}" -o "${OLDSOFTLEVEL}" = "single" ] \
  561.         && /bin/dmesg -n 1
  562.     
  563.     for x in ${mylevels}
  564.     do
  565.         [ -L "${x}" ] && myscripts="${myscripts} ${x##*/}"
  566.     done
  567. fi
  568.  
  569. # The softscripts dir contains all scripts that belong to the
  570. # runlevel specified in ${svcdir}/softlevel
  571. # It needs to be a new directory, else when stopping the services
  572. # and the old directory is not intact, things get broken
  573.  
  574. mkdir -p -m 0755 "${svcdir}/softscripts.new"
  575.  
  576. for x in ${myscripts} ; do
  577.     if [[ ! -e /etc/init.d/${x} ]] ; then
  578.         ewarn "WARNING:  /etc/init.d/${x} missing; skipping ..."
  579.         continue
  580.     fi
  581.     # The -f eliminates a warning if the symlink already exists,
  582.     # which can happen if a service is in both the boot level and
  583.     # the current "normal" runlevel
  584.     ln -snf "/etc/init.d/${x}" "${svcdir}/softscripts.new/${x}"
  585. done
  586.  
  587. dep_stop() {
  588.     local x=
  589.     local dep=
  590.     local needsme=
  591.     local myservice="${1##*/}"
  592.     local depservice=
  593.  
  594.     if ! service_started "${myservice}"
  595.     then
  596.         return 0
  597.     fi
  598.     
  599.     # Candidate for zapping
  600.     if [ ! -L "${svcdir}/softscripts.new/${myservice}" ]
  601.     then
  602.         # If this is a 'net' service, we do not want to stop it if it was
  603.         # not in the previous runlevel, and we are not shutting down,
  604.         # rebooting or going to single runlevel.  This is because the user
  605.         # might have started it (net.ppp?), or possibly hotplug ...
  606.         if net_service "${myservice}" && \
  607.            [ "${SOFTLEVEL}" != "reboot" -a \
  608.              "${SOFTLEVEL}" != "shutdown" -a \
  609.              "${SOFTLEVEL}" != "single" ]
  610.         then
  611.             if [ -n "${OLDSOFTLEVEL}" ] && \
  612.                ! in_runlevel "${myservice}" "${OLDSOFTLEVEL}"
  613.             then
  614.                 # This service is not in the previous runlevel, so
  615.                 # do not stop it ...
  616.                 return 0
  617.             fi
  618.         fi
  619.  
  620.         # Should not work for 'use'
  621.         if [ -z "$(needsme "${myservice}")" ]
  622.         then
  623.             # Nothing depends on me
  624.             stop_service "${myservice}"
  625.         else
  626.             # Something may depend on me
  627.             needsme=0
  628.             
  629.             for dep in $(needsme "${myservice}")
  630.             do
  631.                 if service_started "${dep}" && \
  632.                    [ -L "${svcdir}/softscripts.new/${dep}" ]
  633.                 then
  634.                     # This dep is valid
  635.                     needsme=1
  636.                     
  637.                     break
  638.                 fi
  639.             done
  640.             
  641.             if [ "${needsme}" -eq 0 ]
  642.             then
  643.                 stop_service "${myservice}"
  644.             fi
  645.         fi
  646.     fi
  647. }
  648.  
  649. # Stop services
  650. if [[ ${SOFTLEVEL} != "single" && \
  651.       ${SOFTLEVEL} != "reboot" && \
  652.       ${SOFTLEVEL} != "shutdown" ]]
  653. then
  654.     for i in $(dolisting "${svcdir}/started/") ; do
  655.         dep_stop "${i}"
  656.     done
  657. else
  658.     get_critical_services
  659.  
  660.     is_critical_service() {
  661.         local x
  662.         local myservice=${1##*/}
  663.  
  664.         for x in ${CRITICAL_SERVICES} ; do
  665.             [[ ${myservice} == "${x}" ]] && return 0
  666.         done
  667.  
  668.         return 1
  669.     }
  670.     
  671.     # First stop non critical services
  672.     for i in $(dolisting "${svcdir}/started/")
  673.     do
  674.         if [ -n "${LOGGER_SERVICE}" ]
  675.         then
  676.             # Only stop it if the logger do not depends on it
  677.             if ! query_before "${i##*/}" "${LOGGER_SERVICE}"
  678.             then
  679.                 continue
  680.             fi
  681.         fi
  682.  
  683.         # Do not stop critical services just yet
  684.         is_critical_service "${i}" || dep_stop "${i}"
  685.     done
  686.  
  687.     # Now stop the logger if running
  688.     if [ -n "${LOGGER_SERVICE}" ]
  689.     then
  690.         dep_stop "${LOGGER_SERVICE}"
  691.     fi
  692.  
  693.     # Now stop the rest
  694.     for i in $(dolisting "${svcdir}/started/")
  695.     do
  696.         dep_stop "${i}"
  697.     done
  698. fi
  699.  
  700. # Only change softlevel AFTER all the services have been stopped,
  701. # else they will not get the depend's right (wrong SOFTLEVEL)
  702.  
  703. echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
  704.  
  705. if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
  706.     source /sbin/functions.sh
  707.     
  708.     # Clear $svcdir from stale entries, but leave the caches around, as it
  709.     # should help speed things up a bit
  710.     rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
  711.              grep -ve '\(depcache\|deptree\|envcache\)')
  712.     
  713.     source /etc/init.d/halt.sh
  714.     
  715.     if [[ ${SOFTLEVEL} == "reboot" ]] ; then
  716.         source /etc/init.d/reboot.sh
  717.     else
  718.         source /etc/init.d/shutdown.sh
  719.     fi
  720.     
  721.     # Should never get here
  722.     exit 0
  723. fi
  724.  
  725. # Move the old softscritps directory to a different one
  726. # and make the new softscripts directory the current
  727.  
  728. mv -f "${svcdir}/softscripts" "${svcdir}/softscripts.old"
  729. mv -f "${svcdir}/softscripts.new" "${svcdir}/softscripts"
  730.  
  731. dep_start() {
  732.     local myservice="${1##*/}"
  733.  
  734.     [ ! -L "${svcdir}/softscripts/${myservice}" ] && continue
  735.  
  736.     # Only start a script if it isn't already running
  737.     service_started "${myservice}" || schedule_service_startup "${myservice}"
  738. }
  739.  
  740. get_critical_services
  741.  
  742. EXTRA_SOFTSCRIPTS="${CRITICAL_SERVICES}"
  743.  
  744. if [ -n "${LOGGER_SERVICE}" -a -L "${svcdir}/softscripts/${LOGGER_SERVICE}" ]
  745. then
  746.     service_started "${LOGGER_SERVICE}" || \
  747.         EXTRA_SOFTSCRIPTS="${EXTRA_SOFTSCRIPTS} ${LOGGER_SERVICE}"
  748. fi
  749.  
  750. if [ "${SOFTLEVEL}" != "${BOOTLEVEL}" ]
  751. then
  752.     for i in $(dolisting "/etc/runlevels/${BOOTLEVEL}/")
  753.     do
  754.         [ -L "${svcdir}/softscripts/${i##*/}" ] && \
  755.             EXTRA_SOFTSCRIPTS="${EXTRA_SOFTSCRIPTS} ${i##*/}"
  756.     done
  757. fi
  758.  
  759. # Start scripts
  760. for i in ${EXTRA_SOFTSCRIPTS} $(dolisting "${svcdir}/softscripts/")
  761. do
  762.     dep_start "${i##*/}"
  763. done
  764.  
  765. # Wait for any services that may still be running ...
  766. [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
  767.  
  768. # Clean the old runlevel
  769. rm -rf "${svcdir}/softscripts.old" &>/dev/null
  770.  
  771. # Depends gets nuked, so update them
  772. # (this problem should be solved now, but i think it will be a good idea
  773. #  to recreate the deps after a change in runlevel)
  774.  
  775. #/sbin/depscan.sh &>/dev/null
  776.  
  777. # We want devfsd running after a change of runlevel (this is mostly if we return
  778. # from runlevel 'single')
  779. if [ -z "`ps --no-heading -C 'devfsd'`" -a \
  780.      -n "`gawk '/\/dev devfs/ { print }' /proc/mounts 2>/dev/null`" ]
  781. then
  782.     if [ "${RC_DEVFSD_STARTUP}" != "no" ]
  783.     then
  784.         /sbin/devfsd /dev &>/dev/null
  785.     fi
  786. fi
  787.  
  788. # Runlevel end, so clear stale fail list
  789. rm -rf "${svcdir}/failed" &>/dev/null
  790.  
  791. # If we were in the boot runlevel, it is done now ...
  792. [ -n "${BOOT}" ] && unset BOOT
  793.  
  794. splash "rc_exit"
  795.  
  796. # vim:ts=4
  797.